#pragma once
#include "sio_client.h"

#include <functional>
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <string>
#include <list>

#ifdef WIN32
#define HIGHLIGHT(__O__) std::cout<<__O__<<std::endl
#define EM(__O__) std::cout<<__O__<<std::endl
#endif

#include <stdio.h>
#include <tchar.h>

using namespace sio;
using namespace std;

class SocketObserver {
	virtual void onConnected() = 0;

	virtual void onLogin() = 0;

	virtual void onDisconnected(std::string &reason) = 0;

	virtual void onPeerJoined(std::string &username) = 0;

	virtual void onPeerLeaved(std::string &username) = 0;

	virtual void onMessage(std::string &from, std::string who) = 0;
};

class apSocketIO
{
public:
	apSocketIO();
	~apSocketIO();

	void addObserver(SocketObserver *obs);

	void removeObserver(SocketObserver *obs);

	void on_connected();

	void on_close(client::close_reason const& reason);

	void on_fail();

	void on_ack();

	void connect(const char* url);

	void login(const char* username);

	void send_message(const char* to, const char* msg);

	void logout();

	void disconnect();
private:
	void bind_events();
private:
	std::list<SocketObserver *> m_observers;

	sio::client			m_client;
	socket::ptr			m_current_socket;
	int					m_participants;

	bool				m_connected;

	std::mutex						_lock;
	std::condition_variable_any		_cond;
};

